﻿using System;
using System.Net;

namespace SomeKit.Http
{
    public static partial class HttpHelper
    {
        /// <summary>
        /// Executes a "PUT" method on the resource denoted by <paramref name="uri"/>. Before the request is sent the delegate <paramref name="headerHandler"/> is invoked. 
        /// This is provided for the user, to be able to perform custom manipulation of the header, for ie. custom content- or accept-types or providing special security headers. 
        /// Hereafter, the provided <paramref name="body"/> is written to the request stream, and the request is executed.
        /// Upon completion only one of the delegates <paramref name="resultHandler"/> (in case of success) or <paramref name="errorHandler"/> (in case of failure) is invoked.
        /// </summary>
        /// <param name="uri">The address of the resource, which is being inserted.</param>
        /// <param name="body">The body of the request.</param>
        /// <param name="resultHandler">The delegate to be invoked in case of success.</param>
        /// <param name="errorHandler">The delegate to be invoked in case of failure.</param>
        /// <param name="headerHandler">The delegate provided for custom header customization.</param>
        public static void Put(this Uri uri, string body, Action<string> resultHandler, Action<Exception> errorHandler, Action<HttpWebRequest> headerHandler = null)
        {
            var request = uri.GetRequest(Verbs.PUT, headerHandler);
            request.SendRequest(body, resultHandler, errorHandler);
        }

        /// <summary>
        /// Executes a "PUT" method on the resource denoted by <paramref name="uri"/>. Before the request is sent the delegate <paramref name="headerHandler"/> is invoked. 
        /// This is provided for the user, to be able to perform custom manipulation of the header, for ie. custom content- or accept-types or providing special security headers. 
        /// Upon completion only one of the delegates <paramref name="resultHandler"/> (in case of success) or <paramref name="errorHandler"/> (in case of failure) is invoked.
        /// </summary>
        /// <param name="uri">The address of the resource, which is being inserted.</param>
        /// <param name="resultHandler">The delegate to be invoked in case of success.</param>
        /// <param name="errorHandler">The delegate to be invoked in case of failure.</param>
        /// <param name="headerHandler">The delegate provided for custom header customization.</param>
        public static void Put(this Uri uri, Action<string> resultHandler, Action<Exception> errorHandler, Action<HttpWebRequest> headerHandler = null)
        {
            uri.Put(null, resultHandler, errorHandler, headerHandler);
        }

        /// <summary>
        /// Executes a "PUT" method on the resource denoted by <paramref name="uri"/>. Before the request is sent the delegate <paramref name="headerHandler"/> is invoked. 
        /// This is provided for the user, to be able to perform custom manipulation of the header, for ie. providing special security headers; after this, the content- and accept type is set to application/xml.
        /// Hereafter, the provided <paramref name="body"/> is written to the request stream, and the request is executed.
        /// Upon completion only one of the delegates <paramref name="resultHandler"/> (in case of success) or <paramref name="errorHandler"/> (in case of failure) is invoked.
        /// </summary>
        /// <remarks>
        /// The method does not validate that the body is in valid XML format, nor that the response is valid XML.
        /// </remarks>
        /// <param name="uri">The address of the resource, which is being inserted.</param>
        /// <param name="body">The body of the request.</param>
        /// <param name="resultHandler">The delegate to be invoked in case of success.</param>
        /// <param name="errorHandler">The delegate to be invoked in case of failure.</param>
        /// <param name="headerHandler">The delegate provided for custom header customization.</param>
        public static void PutXml(this Uri uri, string body, Action<string> resultHandler, Action<Exception> errorHandler, Action<HttpWebRequest> headerHandler = null)
        {
            var request = uri.GetXmlRequest(Verbs.PUT, true, headerHandler);
            request.SendRequest(body, resultHandler, errorHandler);
        }

        /// <summary>
        /// Executes a "PUT" method on the resource denoted by <paramref name="uri"/>. Before the request is sent the delegate <paramref name="headerHandler"/> is invoked. 
        /// This is provided for the user, to be able to perform custom manipulation of the header, for ie. providing special security headers; after this, the content- and accept type is set to application/json.
        /// Hereafter, the provided <paramref name="body"/> is written to the request stream, and the request is executed.
        /// Upon completion only one of the delegates <paramref name="resultHandler"/> (in case of success) or <paramref name="errorHandler"/> (in case of failure) is invoked.
        /// </summary>
        /// <remarks>
        /// The method does not validate that the body is in valid JSON format, nor that the response is valid JSON.
        /// </remarks>
        /// <param name="uri">The address of the resource, which is being inserted.</param>
        /// <param name="body">The body of the request.</param>
        /// <param name="resultHandler">The delegate to be invoked in case of success.</param>
        /// <param name="errorHandler">The delegate to be invoked in case of failure.</param>
        /// <param name="headerHandler">The delegate provided for custom header customization.</param>
        public static void PutJson(this Uri uri, string body, Action<string> resultHandler, Action<Exception> errorHandler, Action<HttpWebRequest> headerHandler = null)
        {
            var request = uri.GetJsonRequest(Verbs.PUT, true, headerHandler);
            request.SendRequest(body, resultHandler, errorHandler);
        }
    }
}
